package com.meida.module.bus.provider.service.impl;

import com.alibaba.fastjson.util.TypeUtils;
import com.meida.common.base.entity.EntityMap;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.mybatis.base.service.impl.BaseServiceImpl;
import com.meida.common.mybatis.model.ResultBody;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.utils.DateUtils;
import com.meida.module.bus.client.entity.BusOrder;
import com.meida.module.bus.client.entity.BusOrderAnswer;
import com.meida.module.bus.client.enums.AnswerStateEnum;
import com.meida.module.bus.client.enums.BalanceLogTypeEnum;
import com.meida.module.bus.client.enums.OrderTypeEnum;
import com.meida.module.bus.client.enums.PayStateEnum;
import com.meida.module.bus.provider.mapper.BusOrderAnswerMapper;
import com.meida.module.bus.provider.service.BusOrderAnswerService;
import com.meida.module.bus.provider.service.BusOrderService;
import com.meida.module.pay.provider.service.PayBalanceService;
import com.meida.module.user.client.entity.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 解答表接口实现类
 *
 * @author flyme
 * @date 2021-08-03
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusOrderAnswerServiceImpl extends BaseServiceImpl<BusOrderAnswerMapper, BusOrderAnswer> implements BusOrderAnswerService {

    @Autowired
    private BusOrderService busOrderService;
    @Autowired
    private PayBalanceService payBalanceService;

    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BusOrderAnswer boa, EntityMap extra) {
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterEdit(CriteriaUpdate cu, BusOrderAnswer orderAnswer, EntityMap extra) {
        Integer answerState = FlymeUtils.getInteger(orderAnswer.getAnswerState(), 0);
        if (answerState.equals(0)) {
            return ResultBody.ok("提交成功", orderAnswer);
        } else {
            return ResultBody.msg("");
        }
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<BusOrderAnswer> cq, BusOrderAnswer boa, EntityMap requestMap) {
        cq.orderByDesc("orderAnswer.createTime");
        return ResultBody.ok();
    }

    @Override
    public Boolean saveQuotedPrice(Long orderId, Long scholartyrantId, BigDecimal quotedPrice) {
        BusOrderAnswer busOrderAnswer = new BusOrderAnswer();
        busOrderAnswer.setOrderId(orderId);
        busOrderAnswer.setAnswerUserId(scholartyrantId);
        busOrderAnswer.setQuotedPrice(quotedPrice);
        busOrderAnswer.setAnswerState(AnswerStateEnum.waitAnswer.getValue());
        return save(busOrderAnswer);
    }

    @Override
    public Long countNumByOrderId(Long orderId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.eq("orderId", orderId);
        cq.eq("isAnswer", 1);
        return count(cq);
    }

    @Override
    public Long countNumByOrderIdAndUserId(Long orderId, Long answerUserId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.eq("orderId", orderId);
        cq.eq("answerUserId", answerUserId);
        return count(cq);
    }

    @Override
    public EntityMap getOrderAnswerByOrderIdAndUserId(Long orderId, Long answerUserId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.select(BusOrderAnswer.class, "*");
        cq.eq("orderId", orderId);
        cq.eq(true, "answerUserId", answerUserId);
        return findOne(cq);
    }

    @Override
    public List<EntityMap> selectHomeWorkOrderAnswerList(Long orderId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.select(BusOrderAnswer.class, "orderId", "answerId", "receiveState", "quotedPrice", "answerUserId", "bargainPrice", "updateTime");
        cq.select(AppUser.class, "nickName", "avatar");
        cq.eq(BusOrderAnswer.class, "orderId", orderId);
        cq.eq(BusOrder.class, "orderType", OrderTypeEnum.HomeWork.getValue());
        cq.createJoin(BusOrder.class).setMainField("orderId").setJoinField("orderId");
        cq.createJoin(AppUser.class).setMainField("answerUserId").setJoinField("userId");
        return selectEntityMap(cq);
    }

    @Override
    public Integer countNumByAnswerUserId(Long answerUserId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.eq(BusOrderAnswer.class, "answerUserId", answerUserId);
        cq.eq(BusOrder.class, "answerUserId", answerUserId);
        cq.eq(BusOrderAnswer.class, "isAnswer", 1);
        cq.createJoin(BusOrder.class).setMainField("orderId").setJoinField("orderId");
        return baseMapper.countNumByAnswerUserId(cq);
    }

    @Override
    public Long countNumByAnswerUserId(Long answerUserId, Integer answerState) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.eq("answerUserId", answerUserId);
        cq.eq("answerState", answerState);
        cq.eq("isAnswer", 1);
        return count(cq);
    }

    @Override
    public Boolean setIsAnswer(Long answerId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.eq("answerId", answerId);
        cu.set("isAnswer", 1);
        return update(cu);
    }

    @Override
    public Boolean answerSetIsSettle(Long answerId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.eq("answerId", answerId);
        cu.set("isSettle", 1);
        return update(cu);
    }

    @Override
    public BusOrderAnswer getAnswerByOrderId(Long orderId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.eq("orderId", orderId);
        cq.eq("isAnswer", 1);
        return getOne(cq);
    }

    @Override
    public List<EntityMap> querySettleExpireOrderAnswer() {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.select(BusOrderAnswer.class, "answerId");
        cq.eq("isAnswer", 1);
        cq.eq("isSettle", 0);
        cq.eq("payState", PayStateEnum.HavePay.getValue());
        //结算日期过期
        cq.lt("DATE_FORMAT(settleExpireTime,'%Y-%m-%d %H:%i:%s')", DateUtils.getDateTime());
        cq.createJoin(BusOrder.class).setMainField("orderId").setJoinField("orderId");
        return selectEntityMap(cq);
    }

    @Override
    public void orderAnswerSettleCommission(Long answerId) {
        BusOrderAnswer busOrderAnswer = getById(answerId);
        if (FlymeUtils.isNotEmpty(busOrderAnswer)) {
            Integer answerState = busOrderAnswer.getAnswerState();
            Integer isAnswer = FlymeUtils.getInteger(busOrderAnswer.getIsAnswer(), 0);
            Integer isSettle = FlymeUtils.getInteger(busOrderAnswer.getIsSettle(), 0);
            if (isAnswer.equals(1) && isSettle.equals(0) && AnswerStateEnum.checkPass.getValue().equals(answerState)) {
                Long orderId = busOrderAnswer.getOrderId();
                BusOrder busOrder = busOrderService.getById(orderId);
                if (FlymeUtils.isNotEmpty(busOrder)) {
                    //佣金进行结算
                    Long answerUserId = busOrder.getAnswerUserId();
                    String orderNo = busOrder.getOrderNo();
                    BigDecimal commissionAmount = busOrder.getCommission();
                    String title = "佣金发放";
                    String body = "订单号为" + orderNo + "的佣金已发放";
                    payBalanceService.addBalance(answerUserId, "", commissionAmount, orderNo, BalanceLogTypeEnum.logType3.getValue(), orderId, title, body);
                    //修改订单状态为已完成
                    busOrderService.updateOrderState(orderId, "5");
                    answerSetIsSettle(TypeUtils.castToLong(answerId));
                }
            }
        }
    }

    @Override
    public BigDecimal sumOrderHaveSettleAmount(Long answerUserId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.addSelect("COALESCE(sum(commission),0) havePayCommission");
        cq.eq(BusOrderAnswer.class, "answerUserId", answerUserId);
        cq.eq(BusOrderAnswer.class, "isSettle", 1);
        cq.eq(BusOrder.class, "payState", PayStateEnum.HavePay.getValue());
        cq.createJoin(BusOrder.class).setMainField("orderId").setJoinField("orderId");
        EntityMap one = findOne(cq);
        BigDecimal havePayCommission = one.getBigDecimal("havePayCommission");
        return havePayCommission;
    }

    @Override
    public BigDecimal sumOrderHaveNoSettleAmount(Long answerUserId) {
        CriteriaQuery cq = new CriteriaQuery(BusOrderAnswer.class);
        cq.addSelect("COALESCE(sum(commission),0) haveNoPayCommission");
        cq.eq(BusOrderAnswer.class, "answerUserId", answerUserId);
        cq.eq(BusOrderAnswer.class, "isSettle", 0);
        cq.eq(BusOrder.class, "payState", PayStateEnum.HavePay.getValue());
        cq.eq(BusOrderAnswer.class, "answerState", 2);
        cq.createJoin(BusOrder.class).setMainField("orderId").setJoinField("orderId");
        EntityMap one = findOne(cq);
        BigDecimal haveNoPayCommission = one.getBigDecimal("haveNoPayCommission");
        return haveNoPayCommission;
    }

    @Override
    public ResultBody deleteById(Long answerId) {
        CriteriaUpdate cu = new CriteriaUpdate();
        cu.eq("answerId", answerId);
        cu.set("deleted", 1);
        boolean update = update(cu);
        return ResultBody.ok("删除成功");
    }

}
